动态代理可以动态的创建代理并动态地处理对所代理方法的调用. 在动态代理上所做的所有调用都会被重定向到单一的调用处理器(InvocationHandler)上.
动态代理的例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class DynamicProxyHandler implements InvocationHandler { private Object proxied;
public DynamicProxyHandler(Object proxied) { this.proxied = proxied; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("*** proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args); if (args != null) { for (Object arg : args) { System.out.println(" " + arg); } } Object result = method.invoke(proxied, args); System.out.println("proxy info: " + proxy.toString()); return result; } }
public class SimpleDynamicProxy { public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse("bonobo"); }
public static void main(String[] args) { RealObject real = new RealObject(); consumer(real); Interface proxy = (Interface) Proxy.newProxyInstance( Interface.class.getClassLoader(), new Class[]{Interface.class}, new DynamicProxyHandler(real) ); consumer(proxy); } }
|
在例子中调用proxy的方法如doSomething()会被指向invoke(), 而如果在invoke()中再调用proxy的方法如toString()时,会陷入循环调用的陷阱, 进而抛出Stack Overflow的错误.
参考文献: Thinking in Java Fourth Edition